昨天我們實作了很簡陋的api,今天我們要將它重構成好一點點,至少加入一些錯誤處理。
400、500這些status code,讓我們再發生錯誤的時候,可以得到多一點訊息,而不用面對預設的漏漏長的訊息~ 透過好的錯誤訊息,可以讓我們知道到底發生了甚麼事情,讓維運的夥伴看到後,可以快速的解決難題。
package controller
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import model.*
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
fun customerVOToCustomer(customerVO: CustomerVO) =
    when {
        customerVO.contactInfo.contains("@") -> Customer(
            Name(customerVO.name),
            Email(customerVO.contactInfo),
            Age(customerVO.age)
        )
        customerVO.contactInfo.length > 8 -> throw Error("contactInfo Too Long")
        else -> Customer(Name(customerVO.name), Phone(customerVO.contactInfo), Age(customerVO.age))
    }
@RestController
@SpringBootApplication
open class MyApplication {
    private val customerList = mutableListOf<Customer>()
    @GetMapping("/api/v1/customers")
    fun getAllCustomers(): ResponseEntity<String> {
        if (customerList.isEmpty())
            return ResponseEntity.status(404).body("Not Found any customers!")
        try {
            Json.encodeToString(customerList)
        } catch (e: Exception) {
            return ResponseEntity.status(500).body(e.toString())
        }.let {
            return ResponseEntity.ok(it)
        }
    }
    @PostMapping("/api/v1/customers")
    fun createCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
        Json.decodeFromString<CustomerVO>(newCustomer).let {
            try {
                customerVOToCustomer(it)
            } catch (e: Error) {
                return ResponseEntity.status(400).body(e.toString())
            }
        }.let {
            customerList.add(it)
            it
        }.let {
            try {
                Json.encodeToString(it)
            } catch (e: Exception) {
                return ResponseEntity.status(500).body(e.toString())
            }
        }.let {
            return ResponseEntity.ok(it)
        }
    }
    @PutMapping("/api/v1/customers")
    fun updateCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
        Json.decodeFromString<CustomerVO>(newCustomer).let {
            customerVOToCustomer(it)
        }.let { validatedCustomer ->
            return when (val index = customerList.indexOfFirst { it.name == validatedCustomer.name }) {
                -1 -> ResponseEntity.status(404).body("Not Found")
                else -> {
                    customerList.set(index, validatedCustomer)
                    ResponseEntity.ok("Modify success")
                }
            }
        }
    }
    @DeleteMapping("/api/v1/customers")
    fun DeleteCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
        Json.decodeFromString<CustomerVO>(newCustomer).let {
            customerVOToCustomer(it)
        }.let { validatedCustomer ->
            return when (val index = customerList.indexOfFirst { it.name == validatedCustomer.name }) {
                -1 -> ResponseEntity.status(404).body("Not Found")
                else -> {
                    customerList.removeAt(index)
                    ResponseEntity.ok("Delete success")
                }
            }
        }
    }
}
fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}
我們今天將一些常見的錯誤做了處理,至少回傳一些大家看得懂的status,並且透過一些訊息,我們可以知道大概發生了什麼樣的錯誤,比如說找不到顧客呀,成功修改顧客資訊等,當我們寫得越清楚,當真正錯誤發生時,我們可以一目了然的知道要怎麼處理,接下來,明天要再對錯誤更進一步的進行處理,加上domain type的概念。
這邊附上GPT夥伴幫我們製作常見的status code介紹。
| 狀態碼 | 說明 | 用途範例 | 
|---|---|---|
| 200 | OK | 請求成功完成。 | 
| 201 | Created | 請求成功,並且新資源已經被創建。 | 
| 204 | No Content | 請求成功,但沒有返回主體內容。 | 
| 400 | Bad Request | 請求無效或格式錯誤。 | 
| 401 | Unauthorized | 未經授權,需要驗證。 | 
| 403 | Forbidden | 請求被拒絕,沒有訪問權限。 | 
| 404 | Not Found | 請求的資源不存在。 | 
| 405 | Method Not Allowed | 不允許使用該HTTP方法。 | 
| 500 | Internal Server Error | 伺服器內部錯誤,請求未完成。 | 
| 502 | Bad Gateway | 伺服器作為網關或代理,從上游伺服器收到無效回應。 | 
| 503 | Service Unavailable | 伺服器暫時無法處理請求(通常用於維護模式)。 | 
| 504 | Gateway Timeout | 伺服器作為網關或代理,未及時收到上游伺服器的回應。 |